#pragma once
#include <game/Config.h>

#include <Atom.h>
#include <boost/shared_ptr.hpp>
#include <boost/function.hpp>

ARELLO_GAME_NAMESPACE_DECL_START
namespace controls {

class Control;

/** Abstract interface to separate the guy who holds controls from the guy who needs them
*
*	It is implied that this interface implementation have exclusive ownership over all 
*	controls they have.
*/
class ControlCollection
{
public:
	virtual ~ControlCollection() { }

	virtual boost::shared_ptr<Control> FindControl(const liba::Atom& name) = 0;
	template <typename T>
	boost::shared_ptr<T> FindControl(const liba::Atom& name)
	{
		boost::shared_ptr<Control> result = this->FindControl(name);
		if (result)
			return boost::dynamic_pointer_cast<T>(result);

		return boost::shared_ptr<T>();
	}

	virtual void ForEach(boost::function<void (boost::shared_ptr<Control>)> fn) = 0;
	virtual void Add(boost::shared_ptr<Control> c) = 0;
	virtual boost::shared_ptr<Control> Remove(Control* c) = 0;
};

} // namespace controls
ARELLO_GAME_NAMESPACE_DECL_END